/*
@auther fenglei
*/
package xxdb

import (
	"fmt"
	"gitee.com/fenglei-l/ops-util/xxlog"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
	"time"
)

// MySQLOptions defines options for mysql database.
type MySQLOptions struct {
	DSN                   string
	MaxIdleConnections    int
	MaxOpenConnections    int
	MaxConnectionLifeTime time.Duration
	// +optional
	LogLevel logger.LogLevel
}

// NewMySQL create a new gorm db instance with the given options.
func NewMySQL(opts *MySQLOptions) (*gorm.DB, error) {
	if opts.DSN == "" {
		return nil, fmt.Errorf("DNS is nil")
	}
	// Set default values to ensure all fields in opts are available.
	setMySQLDefaults(opts)
	logs := xxlog.NewGormLogger().LogMode(opts.LogLevel)
	db, err := gorm.Open(mysql.Open(opts.DSN), &gorm.Config{
		// PrepareStmt executes the given query in cached statement.
		// This can improve performance.
		PrepareStmt: true,
		Logger:      logs,
	})
	if err != nil {
		return nil, err
	}
	sqlDB, err := db.DB()
	if err != nil {
		return nil, err
	}
	// SetMaxOpenConns sets the maximum number of open connections to the database.
	sqlDB.SetMaxOpenConns(opts.MaxOpenConnections)
	// SetConnMaxLifetime sets the maximum amount of time a connection may be reused.
	sqlDB.SetConnMaxLifetime(opts.MaxConnectionLifeTime)
	// SetMaxIdleConns sets the maximum number of connections in the idle connection pool.
	sqlDB.SetMaxIdleConns(opts.MaxIdleConnections)
	return db, nil
}

// setMySQLDefaults set available default values for some fields.
func setMySQLDefaults(opts *MySQLOptions) {
	if opts.MaxIdleConnections == 0 {
		opts.MaxIdleConnections = 10
	}
	if opts.MaxOpenConnections == 0 {
		opts.MaxOpenConnections = 100
	}
	if opts.MaxConnectionLifeTime == 0 {
		opts.MaxConnectionLifeTime = time.Hour
	}
	if opts.LogLevel <= 0 {
		opts.LogLevel = logger.Info
	}
}
func CloseMySQL(db *gorm.DB) error {
	if db != nil {
		sqlDB, err := db.DB()
		if err != nil {
			return err
		}
		return sqlDB.Close()
	}
	return nil
}
